`timescale 1ns/1ps
module top_tb();

parameter ARR_Len = 8  ;
parameter EXP_Wid = 3  ;
parameter MSA_Wid = 3  ;
parameter Eshare_Wid= 3;
parameter OUT_Wid = 2 * (2 ** EXP_Wid + MSA_Wid - 1 + 2 ** Eshare_Wid - 1);
parameter SUM_Wid = OUT_Wid;
parameter Fra_Wid = 7;

reg                                     clk         = 1'b0;

integer                                 addr_reg    = 0;
reg [ARR_Len*(EXP_Wid+MSA_Wid+1)-1:0]   in_a_tbl    [0:4106];
reg [ARR_Len*(EXP_Wid+MSA_Wid+1)-1:0]   in_b_tbl    [0:4106];
reg [Eshare_Wid-1:0]                    exp_a_tbl   [0:4106];
reg [Eshare_Wid-1:0]                    exp_b_tbl   [0:4106];

initial begin
    $readmemb("../TB/in_a.txt",in_a_tbl);
    $readmemb("../TB/in_b.txt",in_b_tbl);
    $readmemb("../TB/exp_a.txt",exp_a_tbl);
    $readmemb("../TB/exp_b.txt",exp_b_tbl);
end

reg                                     out_en_i    = 1'b1;
wire                                    out_en_o    ;
wire[ARR_Len*(EXP_Wid+MSA_Wid+1)-1:0]   in_a        = in_a_tbl[addr_reg];
wire[ARR_Len*(EXP_Wid+MSA_Wid+1)-1:0]   in_b        = in_b_tbl[addr_reg];
wire[Eshare_Wid-1:0]                    exp_share_a = exp_a_tbl[addr_reg];
wire[Eshare_Wid-1:0]                    exp_share_b = exp_b_tbl[addr_reg];
wire[ARR_Len*(SUM_Wid          )-1:0]   out_result  ;

initial begin
    repeat(2*ARR_Len) @(posedge clk);// flush and reset the result regs！
    #0.1 out_en_i = 1'b0;// reset done.

	repeat(4096+ARR_Len) @(posedge clk)// There are 100 datas and arr_size=8, so need 108 cycles to input.
        #0.1 addr_reg = addr_reg + 1;

    #0.1 out_en_i = 1'b1;//caculate done!
    repeat(ARR_Len) @(posedge clk);//output done!
    #0.1 out_en_i = 1'b0;
end

always #1 clk <= ~clk;

top_systolic_expshare #(
    .ARR_Len        (ARR_Len    ),
    .EXP_Wid        (EXP_Wid    ),
    .MSA_Wid        (MSA_Wid    ),
    .Eshare_Wid     (Eshare_Wid ),
    .OUT_Wid        (OUT_Wid    ),
    .SUM_Wid        (SUM_Wid    ),
    .Fra_Wid        (Fra_Wid    )
)u_top(
    .clk            (clk        ),
	.in_a	        (in_a	    ),
	.in_b	        (in_b	    ),
    .exp_share_a    (exp_share_a),
    .exp_share_b    (exp_share_b),
    .out_en_i       (out_en_i   ),
    .out_en_o       (out_en_o   ),
	.out_result		(out_result )
);

initial 
begin
    // $fsdbDumpfile("test.fsdb");
    // $fsdbDumpvars(0);
	$fsdbDumpvars("+IO_Only");
end
initial 
begin
    $set_toggle_region(u_top);
	@(negedge out_en_i);
    @(posedge clk);
	$toggle_start;
	
    @(negedge out_en_i);
	@(negedge out_en_o);
	$toggle_stop;
	$toggle_report("../Synthesize/results/backward_syn.saif",1.0e-12,"u_top");
end
initial 
begin
    $sdf_annotate("../Synthesize/results/top_systolic_expshare.sdf",u_top);
end
endmodule